#region Copyright(c) 2006 ZO, All right reserved.
// -----------------------------------------------------------------------------
// Copyright(c) 2006 ZO, All right reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1.  Redistribution of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//   2.  Redistribution in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//   3.  The name of the author may not be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
#endregion


#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
using ArgumentNullException = ZO.SmartCore.Core.ArgumentNullException;
using ArgumentException = ZO.SmartCore.Core.ArgumentException;
using ArgumentOutOfRangeException = ZO.SmartCore.Core.ArgumentOutOfRangeException;
using ZO.SmartCore.Core;
using System.Globalization;
using ZO.SmartCore.Interop.Windows;
using System.Threading;
#endregion

namespace ZO.SmartCore.Logger
{
    /// <summary>
    /// Represents a log message. 
    /// Contains the common properties that are required for all log messages. 
    /// </summary>
    public class LogEntry : ICloneable<LogEntry>
    {

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="LogEntry"/> class.
        /// </summary>
        public LogEntry()
        {
        }

        /// <summary>
        /// Create a new instance of <see cref="LogEntry" /> with a full set of constructor parameters
        /// </summary>
        /// <param name="message">Message body to log.</param>
        /// <param name="severity">Log entry severity as a <see cref="Severity" /> enumeration.</param>
        /// <param name="title">Additional description of the log entry message.</param>
        public LogEntry(string message, Severity severity, string title)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            this.Message = message;
            this.Severity = severity;
            this.Title = title;
        }

        /// <summary>
        /// Create a new instance of <see cref="LogEntry" /> with a full set of constructor parameters
        /// </summary>
        /// <param name="message">Message body to log.</param>
        /// <param name="severity">Log entry severity as a <see cref="Severity" /> enumeration.</param>
        public LogEntry(string message, Severity severity) : this(message, severity, "")
        {
        
        }


        /// <summary>
        /// Create a new instance of <see cref="LogEntry" /> with a full set of constructor parameters
        /// </summary>
        /// <param name="message">Message body to log.</param>
        /// <param name="title">Additional description of the log entry message.</param>
        public LogEntry(string message, string title) : this(message, Severity.Information, title)
        {
        }

        /// <summary>
        /// Create a new instance of <see cref="LogEntry" /> with a full set of constructor parameters
        /// </summary>
        /// <param name="message">Message body to log.</param>
        public LogEntry(string message)
            : this(message, Severity.Information, "")
        {
        }

        #endregion

        #region Destructor

        #endregion

        #region Fields
        private Severity _Severity = Severity.Information;

        private long _Win32ThreadID = Window.ThreadID;

        private string _Title;

        private DateTime _TimeStamp = DateTime.Now;

        private string _ProcessName = Window.ProcessName;

        private long _ProcessID = Window.ProcessID;

        private string _ManagedThreadName = Thread.CurrentThread.Name;

        private string _MachineName = Environment.MachineName;

        private string _AppDomainName = AppDomain.CurrentDomain.FriendlyName;

        private string _Message;
        #endregion

        #region Events

        #endregion

        #region Operators

        #endregion

        #region Properties

        /// <summary>
        /// Log entry severity as a <see cref="Severity" /> enumeration.
        /// </summary>
        public Severity Severity
        {
            get
            {
                return this._Severity;
            }
            set
            {
                this._Severity = value;
            }
        }

        /// <summary>
        /// Get or Set the name of the .NET thread.
        /// </summary>
        public string ManagedThreadName
        {
            get
            {
                return this._ManagedThreadName;
            }
            set
            {
                this._ManagedThreadName = value;
            }
        }
 

        /// <summary>
        /// The Win32 Thread ID for the current thread.
        /// </summary>
        public long Win32ThreadID
        {
            get
            {
                return this._Win32ThreadID;
            }
            set
            {
                this._Win32ThreadID = value;
            }
        }


        /// <summary>
        /// Additional description of the log entry message.
        /// </summary>
        public string Title
        {
            get
            {
                return this._Title;
            }
            set
            {
                this._Title = value;
            }
        }

        /// <summary>
        /// Date and time of the log entry message.
        /// </summary>
        public DateTime TimeStamp
        {
            get
            {
                return this._TimeStamp;
            }
            set
            {
                this._TimeStamp = value;
            }
        }

        /// <summary>
        /// Read-only property that returns the timeStamp formatted using the current culture.
        /// </summary>
        public string TimeStampString
        {
            get
            {
                return this.TimeStamp.ToString(CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        /// The name of the current running process.
        /// </summary>
        public string ProcessName
        {
            get
            {
                return this._ProcessName;
            }
            set
            {
                this._ProcessName = value;
            }
        }

        /// <summary>
        /// The Win32 process ID for the current running process.
        /// </summary>
        public long ProcessID
        {
            get
            {
                return this._ProcessID;
            }
            set
            {
                this._ProcessID = value;
            }
        }


        /// <summary>
        /// Get or Set the name of the computer.
        /// </summary>
        public string MachineName
        {
            get
            {
                return this._MachineName;
            }
            set
            {
                this._MachineName = value;
            }
        }

        /// <summary>
        /// Get or Set the <see cref="System.AppDomain" /> in which the program is running.
        /// </summary>
        public string AppDomainName
        {
            get
            {
                return this._AppDomainName;
            }
            set
            {
                this._AppDomainName = value;
            }
        }


        /// <summary>
        /// Message body to log.  Value from ToString() method from message object.
        /// </summary>
        public string Message
        {
            get
            {
                return this._Message;
            }
            set
            {
                this._Message = value;
            }
        }
 

        #endregion

        #region Methods

        #endregion
   
        #region ICloneable<LogEntry> Members

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public LogEntry Clone()
        {
            LogEntry entry = new LogEntry();
            entry.Message = this.Message;
            entry.Title = this.Title;
            entry.Severity = this.Severity;
            entry.TimeStamp = this.TimeStamp;
            entry.MachineName = this.MachineName;
            entry.AppDomainName = this.AppDomainName;
            entry.ProcessID = this.ProcessID;
            entry.ProcessName = this.ProcessName;
            entry.ManagedThreadName = this.ManagedThreadName;
            return entry;
        }

        #endregion
    }
}
